package imaSyncPull

import (
	"errors"
	"fmt"
	"local/config"
	"local/loger"
	"log"
	"sort"
	"strconv"
	"time"
	youduModel "youdu/model"
)

var (
	logger    *loger.Logger
	deptStats *loger.SyncStats
	userStats *loger.SyncStats
)

func init() {
	// 创建日志记录器，设置30天的日志保留期
	logger = loger.NewLogger("", "imaSyncPull", 30)
}

// processDepartments 递归处理部门及其子部门
func processDepartments(dept Department, successDepts *map[int]FlatDepartment) error {
	deptStats.IncrTotal()

	//  sleep 100ms 避免接口调用频繁
	time.Sleep(100 * time.Millisecond)

	// 转换 parentId 为整数
	parentID, err := strconv.Atoi(dept.ParentID)
	if err != nil {
		errMsg := fmt.Sprintf("转换部门父ID失败 [%s]: %v", dept.ParentID, err)
		deptStats.AddError(errMsg)
		return errors.New(errMsg)
	}

	// 构造有度部门结构体
	yd := youduModel.DepartmentInfo{
		Id:       dept.ID,
		Name:     dept.Name,
		ParentId: parentID,
	}

	// 根据删除标志处理部门
	switch dept.DelFlag {
	case "0":
		// 保存或更新部门
		if err := youduOrg.DepartmentSave(yd); err != nil {
			errMsg := fmt.Sprintf("保存部门失败 [%d]: %v", dept.ID, err)
			deptStats.AddError(errMsg)
			return errors.New(errMsg)
		}
		deptStats.AddSuccess()
		deptStats.IncrAdded() // 全量同步时，所有保存的部门都视为新增
		(*successDepts)[dept.ID] = FlatDepartment{
			ID:       dept.ID,
			ParentID: dept.ParentID,
			Name:     dept.Name,
			DelFlag:  dept.DelFlag,
			Sort:     dept.Sort,
		}
	case "1":
		// 删除部门
		if err := youduOrg.DepartmentDelete(dept.ID); err != nil {
			errMsg := fmt.Sprintf("删除部门失败 [%d]: %v", dept.ID, err)
			deptStats.AddError(errMsg)
			return errors.New(errMsg)
		}
		deptStats.AddSuccess()
		deptStats.IncrDeleted()
	}

	// 递归处理子部门
	for _, child := range dept.Children {
		if err := processDepartments(child, successDepts); err != nil {
			return err
		}
	}

	return nil
}

// processUser 处理单个用户
func processUser(user User, successUsers *[]User) error {
	userStats.IncrTotal()

	//  sleep 100ms 避免接口调用频繁
	time.Sleep(100 * time.Millisecond)

	// 根据用户状态确定启用状态
	state := 0
	if user.UserStatus == "0" && user.LoginFlag == "1" && user.DelFlag == "0" {
		state = 1
	}

	// 转换性别格式
	// 国能：男1，女2
	// 有度：0表示男性，1表示女性
	sex := 0
	switch user.Gender {
	case 1:
		sex = 0
	case 2:
		sex = 1
	}

	// 优先使用工号作为账号
	username := user.No
	if username == "" {
		username = user.LoginName
	}

	// 构造有度用户结构体
	yd := youduModel.UserInfo{
		UserId:      username,
		Name:        user.Name,
		Dept:        []int{user.OrgID},
		Mobile:      user.Mobile,
		Email:       user.Email,
		Phone:       user.Phone,
		Gender:      sex,
		EnableState: state,
	}

	// 保存用户信息
	if err := youduOrg.UserSave(yd); err != nil {
		errMsg := fmt.Sprintf("保存用户失败 [%s]: %v", user.LoginName, err)
		userStats.AddError(errMsg)
		return errors.New(errMsg)
	}

	userStats.AddSuccess()
	userStats.IncrAdded() // 全量同步时，所有保存的用户都视为新增
	*successUsers = append(*successUsers, user)
	return nil
}

// procDepartments 处理增量部门同步
func procDepartments(currentDepts []Department, cachedDepts map[int]FlatDepartment) (map[int]FlatDepartment, error) {
	// 用于存储成功同步的部门
	successDepts := make(map[int]FlatDepartment)
	// 用于存储当前处理的部门
	cachedDeptsCurrent := make(map[int]FlatDepartment)

	// 处理当前部门
	for _, dept := range currentDepts {
		deptStats.IncrTotal()
		time.Sleep(100 * time.Millisecond)

		// 转换 parentId 为整数
		parentID, err := strconv.Atoi(dept.ParentID)
		if err != nil {
			errMsg := fmt.Sprintf("转换部门父ID失败 [%s]: %v", dept.ParentID, err)
			deptStats.AddError(errMsg)
			continue
		}

		// 构造有度部门结构体
		yd := youduModel.DepartmentInfo{
			Id:       dept.ID,
			Name:     dept.Name,
			ParentId: parentID,
		}

		// 将当前部门添加到当前处理映射表中
		cachedDeptsCurrent[dept.ID] = FlatDepartment{
			ID:       dept.ID,
			ParentID: dept.ParentID,
			Name:     dept.Name,
			DelFlag:  dept.DelFlag,
			Sort:     dept.Sort,
		}

		// 检查部门是否在缓存中
		if cachedDept, exists := cachedDepts[dept.ID]; !exists {
			// 新增部门
			if err := youduOrg.DepartmentSave(yd); err != nil {
				errMsg := fmt.Sprintf("保存新部门失败 [%d]: %v", dept.ID, err)
				deptStats.AddError(errMsg)
				continue
			}
			deptStats.AddSuccess()
			deptStats.IncrAdded()
			successDepts[dept.ID] = FlatDepartment{
				ID:       dept.ID,
				ParentID: dept.ParentID,
				Name:     dept.Name,
				DelFlag:  dept.DelFlag,
				Sort:     dept.Sort,
			}
		} else {
			// 检查部门信息是否有变化
			cachedParentID, _ := strconv.Atoi(cachedDept.ParentID)
			if cachedDept.Name != dept.Name || cachedParentID != parentID {
				// 更新部门
				if err := youduOrg.DepartmentSave(yd); err != nil {
					errMsg := fmt.Sprintf("更新部门失败 [%d]: %v", dept.ID, err)
					deptStats.AddError(errMsg)
					continue
				}
				deptStats.AddSuccess()
				deptStats.IncrModified()
				successDepts[dept.ID] = FlatDepartment{
					ID:       dept.ID,
					ParentID: dept.ParentID,
					Name:     dept.Name,
					DelFlag:  dept.DelFlag,
					Sort:     dept.Sort,
				}
			} else {
				// 部门没有变化，也加入成功列表
				successDepts[dept.ID] = cachedDept
			}
		}

		// 递归处理子部门
		successChildren, err := procDepartments(dept.Children, cachedDepts)
		if err != nil {
			return nil, err
		}
		// 将子部门添加到成功列表和当前处理映射表中
		for id, child := range successChildren {
			successDepts[id] = child
			cachedDeptsCurrent[id] = child
		}
	}

	return successDepts, nil
}

// deleteDepartments 处理需要删除的部门
func deleteDepartments(cachedDepts map[int]FlatDepartment, cachedDeptsCurrent map[int]FlatDepartment) {
	log.Println("开始检查需要删除的部门...")

	// 将部门ID转换为切片以便排序
	var deptIDs []int
	for id := range cachedDepts {
		deptIDs = append(deptIDs, id)
	}

	// 按ID倒序排序（假设ID越大表示层级越深）
	sort.Sort(sort.Reverse(sort.IntSlice(deptIDs)))

	// 倒序删除部门
	for _, id := range deptIDs {
		// 如果部门在缓存中存在但在当前处理映射表中不存在，说明该部门已被删除
		if _, exists := cachedDeptsCurrent[id]; !exists {
			// 删除部门
			if err := youduOrg.DepartmentDelete(id); err != nil {
				errMsg := fmt.Sprintf("删除部门失败 [%d]: %v", id, err)
				deptStats.AddError(errMsg)
				continue
			}
			deptStats.AddSuccess()
			deptStats.IncrDeleted()
		}
	}
	log.Println("完成检查需要删除的部门")
}

// procUser 处理增量用户同步
func procUser(currentUsers []User, cachedUsers []User) ([]User, error) {
	// 创建缓存用户映射
	cachedUserMap := make(map[string]User)
	for _, user := range cachedUsers {
		cachedUserMap[user.LoginName] = user
	}

	// 用于存储成功同步的用户
	successUsers := make([]User, 0)

	// 处理当前用户
	for _, user := range currentUsers {
		userStats.IncrTotal()
		time.Sleep(100 * time.Millisecond)

		// 根据用户状态确定启用状态
		state := 0
		if user.UserStatus == "0" && user.LoginFlag == "1" && user.DelFlag == "0" {
			state = 1
		}
		// 优先使用工号作为账号
		username := user.No
		if username == "" {
			username = user.LoginName
		}

		// 转换性别格式
		// 国能：男1，女2
		// 有度：0表示男性，1表示女性
		sex := 0
		switch user.Gender {
		case 1:
			sex = 0
		case 2:
			sex = 1
		}

		// 构造有度用户结构体
		yd := youduModel.UserInfo{
			UserId:      username,
			Name:        user.Name,
			Dept:        []int{user.OrgID},
			Mobile:      user.Mobile,
			Email:       user.Email,
			Phone:       user.Phone,
			Gender:      sex,
			EnableState: state,
		}

		// 检查用户是否在缓存中
		if cachedUser, exists := cachedUserMap[user.LoginName]; !exists {
			// 新增用户
			if err := youduOrg.UserSave(yd); err != nil {
				errMsg := fmt.Sprintf("保存新用户失败 [%s]: %v", username, err)
				userStats.AddError(errMsg)
				continue
			}
			userStats.AddSuccess()
			userStats.IncrAdded()
			successUsers = append(successUsers, user)
		} else if cachedUser.Name != user.Name ||
			cachedUser.Email != user.Email ||
			cachedUser.Phone != user.Phone ||
			cachedUser.Mobile != user.Mobile ||
			cachedUser.Gender != user.Gender ||
			cachedUser.OrgID != user.OrgID {
			// 更新用户
			if err := youduOrg.UserSave(yd); err != nil {
				errMsg := fmt.Sprintf("更新用户失败 [%s]: %v", username, err)
				userStats.AddError(errMsg)
				continue
			}
			userStats.AddSuccess()
			userStats.IncrModified()
			successUsers = append(successUsers, user)
		} else {
			// 用户没有变化，也加入成功列表
			successUsers = append(successUsers, user)
		}
	}

	// 检查需要删除的用户
	for _, cachedUser := range cachedUsers {
		found := false
		for _, currentUser := range currentUsers {
			if currentUser.LoginName == cachedUser.LoginName {
				found = true
				break
			}
		}
		if !found {
			// 删除用户
			// 优先使用工号作为账号
			username := cachedUser.No
			if username == "" {
				username = cachedUser.LoginName
			}
			if err := youduOrg.UserDelete(username); err != nil {
				errMsg := fmt.Sprintf("删除用户失败 [%s]: %v", username, err)
				userStats.AddError(errMsg)
				continue
			}
			userStats.AddSuccess()
			userStats.IncrDeleted()
		}
	}

	return successUsers, nil
}

// SyncData 同步部门和用户数据
func SyncData() error {
	updateConfig()

	// 初始化统计信息
	deptStats = loger.NewSyncStats()
	userStats = loger.NewSyncStats()

	// 记录开始同步
	logger.Log("开始同步数据...")

	// 获取当前数据
	departments, err := GetAllDepartments()
	if err != nil {
		errMsg := fmt.Sprintf("获取部门列表失败: %v", err)
		logger.Log(errMsg)
		return errors.New(errMsg)
	}

	users, err := GetAllUsers()
	if err != nil {
		errMsg := fmt.Sprintf("获取用户列表失败: %v", err)
		logger.Log(errMsg)
		return errors.New(errMsg)
	}

	// 加载缓存数据
	cache, err := LoadCache()
	if err != nil || cache == nil {
		logger.Log("加载缓存失败或缓存为空，执行全量同步")
		// 清理有度端现有数据
		err2 := youduOrg.DeptClear(0)
		if err2 != nil {
			logger.Log("清理有度端数据失败: " + err2.Error())
		} else {
			// for _, log := range logs {
			// 	logger.Log(log)
			// }
			logger.Log("清理有度端数据完成，开始执行全量同步")
		}
		// os.Exit(0)
		// 执行全量同步
		successDepts := make(map[int]FlatDepartment)
		successUsers := make([]User, 0)

		for _, dept := range departments {
			if err := processDepartments(dept, &successDepts); err != nil {
				continue
			}
		}
		for _, user := range users {
			if err := processUser(user, &successUsers); err != nil {
				continue
			}
		}

		// 保存全量同步的数据到缓存
		newCache := &SyncCache{
			Departments: successDepts,
			Users:       successUsers,
			LastSync:    time.Now().Format(time.RFC3339),
		}
		if err := SaveCache(newCache); err != nil {
			logger.Log("保存全量同步缓存失败")
		}
	} else {
		// 执行增量同步
		successDepts, err := procDepartments(departments, cache.Departments)
		if err != nil {
			logger.Log("部门增量同步失败")
		}

		// 先处理用户
		successUsers, err := procUser(users, cache.Users)
		if err != nil {
			logger.Log("用户增量同步失败")
		}

		// 最后处理需要删除的部门
		deleteDepartments(cache.Departments, successDepts)

		// 保存新的缓存数据
		newCache := &SyncCache{
			Departments: successDepts,
			Users:       successUsers,
			LastSync:    time.Now().Format(time.RFC3339),
		}
		if err := SaveCache(newCache); err != nil {
			logger.Log("保存缓存失败")
		}
	}

	// 记录同步摘要
	logger.Log(deptStats.Summary("部门"))
	logger.Log(userStats.Summary("用户"))

	return nil
}

func updateConfig() {
	// 更新配置文件
	baseURL = config.Inst.ImaApi.Server
	authUser = config.Inst.ImaApi.AuthUser
	authPassword = config.Inst.ImaApi.AuthPassword
	authKey = config.Inst.ImaApi.AuthKey
	youduOrg.Server = config.Inst.Entprise.YouduServer
	youduOrg.Buin = config.Inst.Entprise.Buin
	youduOrg.AppId = config.Inst.YouduAppOrg.AppId
	youduOrg.EncodedAesKey = config.Inst.YouduAppOrg.AesKey
}
